In [1]:
import sys
import os
import contextlib
import pandas as pd
import altair as alt
alt.data_transformers.enable("vegafusion")
sys.path.append(os.path.abspath(os.path.join('..', 'src')))
from gridSavers import (
optimize_battery_schedule_df_flexible_end,
run_weekly_optimization_with_daily_usage,
simulate_all_nodes,
prepare_visualization,
plot_altair_separate
)
Grid Savers: Potential Benifits to Utilize V2G¶
By Rafe Chang, Manjari Asawa, Ruben Darancou
Repo Link: https://github.com/rafecchang/gridSavers
Using a Vehicle to Grid (V2G) system, utilities can benifit from lower residential demands during peak hours, which cuts the cost of purchasing electricity in the wholesale power market. In this report, we are interested in simulating the implementastion of such technology.
Introduction¶
placeholderintroduce CAISOplaceholderintroduce V2G
Assumptions¶
- The capacity of hardware, software, and regulation is supportive for this technology to implement
- The reduce in demand will not effect wholesale electricity pricing
Data¶
- Local Marginal Price (LMP) of the Day Ahead Market (DAM) in CAISO on May 5th and May6th.
- Retrieved throught CAISO's OASIS Website
- PRICES/ Energy Prices/ Locational Marginal Prices
- Date From 05/05/2025 to 05/06/2025; Market: DAM; Group: ALL_APNODES
- Loaded as
allNodesin this notebook
- Retrieved throught CAISO's OASIS Website
- LMP of DAM at
POD_ADLIN_1_UNITS-APND- Retrieved throught CAISO's OASIS Website
- PRICES/ Energy Prices/ Locational Marginal Prices
- Date From 04/07/2025 to 05/06/2025; Market: DAM; Group: POD_ADLIN_1_UNITS-APND
- Loaded as
monthlyin this notebook
- Retrieved throught CAISO's OASIS Website
- On average, American drivers drive 30.1 miles everyday.
- For the charger side: We are using the Tesla Wall Connector that has a 11.5 kW output, which is equal to 44 miles. We assume the power input is the same rate.
- For the EV/ battery side: Below is the Useable Battery Capacity of Full Electric Vehicles (Tesla)
| Model | Useable Battery Capacity (kWh) |
|---|---|
| S Dual Motor | 95 |
| S Plaid | 95 |
| X Dual Motor | 95 |
| X Plaid | 95 |
| Y Long Range AWD | 75 |
| Y Long Range AWD Launch Series | 75 |
| Y Long Range RWD | 75 |
| 3 Performance | 75 |
| 3 Long Range Dual Motor | 75 |
| 3 Long Range RWD | 75 |
| Y RWD | 60 |
| 3 | 57.5 |
Preprocessing¶
allNodes and monthly is preprocess with preprocess.ipynb.
Analysis¶
EDA¶
allNodes has 116,112 rows, each role contains the electricity price per MW in the given hour at the given node.
In [2]:
allNodes = pd.read_csv('../data/preprocessed/0506pre.csv')
allNodes['INTERVALSTARTTIME'] = pd.to_datetime(allNodes['INTERVALSTARTTIME'])
allNodes.head()
Out[2]:
| OPR_DT | NODE | MW | INTERVALSTARTTIME | INTERVALENDTIME | Hour_Label | |
|---|---|---|---|---|---|---|
| 0 | 2025-05-05 | AFPR_1_TOT_GEN-APND | 34.41489 | 2025-05-05 00:00:00 | 2025-05-05 01:00:00 | 00:00-01:00 |
| 1 | 2025-05-05 | AFPR_1_TOT_GEN-APND | 34.37762 | 2025-05-05 01:00:00 | 2025-05-05 02:00:00 | 01:00-02:00 |
| 2 | 2025-05-05 | AFPR_1_TOT_GEN-APND | 34.11542 | 2025-05-05 02:00:00 | 2025-05-05 03:00:00 | 02:00-03:00 |
| 3 | 2025-05-05 | AFPR_1_TOT_GEN-APND | 33.97113 | 2025-05-05 03:00:00 | 2025-05-05 04:00:00 | 03:00-04:00 |
| 4 | 2025-05-05 | AFPR_1_TOT_GEN-APND | 34.23300 | 2025-05-05 04:00:00 | 2025-05-05 05:00:00 | 04:00-05:00 |
In [3]:
chart_allNode = alt.Chart(allNodes).mark_line(interpolate='step-after').encode(
x=alt.X('INTERVALSTARTTIME:T', title='Time Interval'),
y=alt.Y('MW:Q', title='Price ($/MWh)'),
color='NODE:N',
tooltip=['NODE', 'Hour_Label', 'MW']
).properties(
title='Day-Ahead LMP ($/MWh) Over Time by Node',
width=800,
height=400
).interactive()
chart_allNode
Out[3]: